package xing2387.filtervideoplayer.filter;

import android.opengl.GLES20;
import android.util.Log;

import xing2387.filtervideoplayer.player.gl.FramebufferObject;

import static android.opengl.GLES20.GL_ARRAY_BUFFER;
import static android.opengl.GLES20.GL_FLOAT;
import static android.opengl.GLES20.GL_TEXTURE0;
import static android.opengl.GLES20.GL_TEXTURE_2D;
import static android.opengl.GLES20.GL_TRIANGLE_STRIP;

/**
 * Created by sudamasayuki on 2017/05/16.
 */

public class GlBlurBackgroundFilter extends GlFilter {

    public static final int GL_TEXTURE_EXTERNAL_OES = 0x8D65;
    private static final String TAG = "GlPreviewFilter";
    int rotate = 0;

//    private static final String VERTEX_SHADER = "uniform mat4 uMVPMatrix;\n"
//            + "uniform mat4 uSTMatrix;\n"
//            + "attribute vec4 aPosition;\n"
//            + "attribute vec4 aTextureCoord;\n"
//            + "varying vec2 vTextureCoord;\n"
//            + "void main() {\n"
//            + "  gl_Position = uMVPMatrix * aPosition;\n"
//            + "  vTextureCoord = (uSTMatrix * aTextureCoord).xy;\n"
//            + "}\n";

//    public int texTarget = GL_TEXTURE_EXTERNAL_OES;

    //    private final static float radius = 20.0f;//偏移量
//    private final static int blurX = 5, blurY = 5;//X方向, Y方向
//    private final static double trans = 0.005d;//透明度
//        private final static String FRAGMENT_SHADER  = "#extension GL_OES_EGL_image_external : require\n" +
//            "precision mediump float;\n" +
//            "varying vec2 vTextureCoord;\n" +
//            "uniform samplerExternalOES sTexture;\n" +
//            "const float resolution = 1024.0;\n" +
//            "const float radius = "+radius+";\n" +
//            "vec2 dir = vec2(1.0,1.0);\n" +
//            "void main() {\n" +
//            "   highp vec4 centralColor = vec4(0.0);\n" +
//            "   float blur = radius/resolution;\n" +
//            "   float hstep = dir.x;\n" +
//            "   float vstep = dir.y;\n" +
//            "   int x = "+blurX+";int y = "+blurY+";\n" +
//            "   for(int i = x; i > 0; i--){\n" +
//            "       for(int j = y; j > 0; j--){\n" +
//            "           centralColor += texture2D(sTexture, vec2(vTextureCoord.x + float(i)*blur*hstep, vTextureCoord.y +float(j)*blur*vstep))*"+trans+";" +
//            "           centralColor += texture2D(sTexture, vec2(vTextureCoord.x - float(i)*blur*hstep, vTextureCoord.y +float(j)*blur*vstep))*"+trans+";" +
//            "           centralColor += texture2D(sTexture, vec2(vTextureCoord.x - float(i)*blur*hstep, vTextureCoord.y -float(j)*blur*vstep))*"+trans+";" +
//            "           centralColor += texture2D(sTexture, vec2(vTextureCoord.x + float(i)*blur*hstep, vTextureCoord.y -float(j)*blur*vstep))*"+trans+";" +
//            "       }\n" +
//            "   }\n" +
//            "   gl_FragColor = vec4(centralColor);\n" +
//            "}";
    public static String getFragmentShader(int width, int height, int backgroundType) {
        width /= 3;
        height /= 3;
        float hStep = 1.0f / width;
        float vStep = 1.0f / height;
        Log.i("mlqtest", "getShader:+width:" + width + "height:" + height + "backgroundType:" + backgroundType);
        int mMaskSize = 9;
//        switch (backgroundType) {
//            case EditConstants.TYPE_BACKGROUND_BLUR_1:
//                mMaskSize = 5;
//                break;
//            case EditConstants.TYPE_BACKGROUND_BLUR_2:
//                mMaskSize = 9;
//                break;
//            case EditConstants.TYPE_BACKGROUND_BLUR_3:
//                mMaskSize = 13;
//                break;
//            case EditConstants.TYPE_BACKGROUND_BLUR_4:
//                mMaskSize = 17;
//                break;
//        }

        return "#extension GL_OES_EGL_image_external : require\n" +
                "precision mediump float;\n" +
                //"in" attributes from our vertex shader
                "varying vec2 vTextureCoord;\n" +

                //declare uniforms
                "uniform samplerExternalOES sTexture;\n" +

                "float normpdf(in float x, in float sigma) {\n" +
                "    return 0.39894 * exp(-0.5 * x * x / (sigma * sigma)) / sigma;\n" +
                "}\n" +


                "void main() {\n" +
                "    vec3 c = texture2D(sTexture, vTextureCoord).rgb;\n" +

                //declare stuff
                "    const int mSize = " + mMaskSize + ";\n" +
                "    const int kSize = (mSize - 1) / 2;\n" +
                "    float kernel[ mSize];\n" +
                "    vec3 final_colour = vec3(0.0);\n" +

                //create the 1-D kernel
                "    float sigma = 7.0;\n" +
                "    float Z = 0.0;\n" +
                "    for (int j = 0; j <= kSize; ++j) {\n" +
                "        kernel[kSize + j] = kernel[kSize - j] = normpdf(float(j), sigma);\n" +
                "    }\n" +

                //get the normalization factor (as the gaussian has been clamped)
                "    for (int j = 0; j < mSize; ++j) {\n" +
                "        Z += kernel[j];\n" +
                "    }\n" +

                //read out the texels
                "    for (int i = -kSize; i <= kSize; ++i) {\n" +
                "        for (int j = -kSize; j <= kSize; ++j) {\n" +
                "            final_colour += kernel[kSize + j] * kernel[kSize + i] * texture2D(sTexture, (vTextureCoord.xy + vec2(float(i)*" + hStep + ", float(j)*" + vStep + "))).rgb;\n" +
                "        }\n" +
                "    }\n" +

                "    gl_FragColor = vec4(final_colour / (Z * Z), 1.0);\n" +
                "}";

    }


    public GlBlurBackgroundFilter(int surfaceWidth, int surfaceHeight, int backgroundType) {
        super(DEFAULT_VERTEX_SHADER, getFragmentShader(surfaceWidth, surfaceHeight, backgroundType));
//        super(VERTEX_SHADER, FRAGMENT_SHADER);

//        this.surfaceWidth=surfaceWidth;
//        this.surfaceHeight=surfaceHeight;
    }

    //    int surfaceWidth;
//    int surfaceHeight;
    int backgroundType;

    @Override
    public void draw(int texName, FramebufferObject fbo) {
        super.draw(texName, fbo);
    }

    public void draw(final int texName, final float[] mvpBlurBackgroundMatrix, final float[] stMatrix, int backgroundType) {
        float aspectRatio = 1.0f;
        useProgram();
        Log.i("mlqtest", "drawBackGround GlBlurBackgroundFilter:" + backgroundType);
        GLES20.glUniformMatrix4fv(getHandle("uMVPMatrix"), 1, false, mvpBlurBackgroundMatrix, 0);
        GLES20.glUniformMatrix4fv(getHandle("uSTMatrix"), 1, false, stMatrix, 0);
        GLES20.glUniform1f(getHandle("uCRatio"), aspectRatio);

        GLES20.glBindBuffer(GL_ARRAY_BUFFER, getVertexBufferName());
        GLES20.glEnableVertexAttribArray(getHandle("aPosition"));
        GLES20.glVertexAttribPointer(getHandle("aPosition"), VERTICES_DATA_POS_SIZE, GL_FLOAT, false, VERTICES_DATA_STRIDE_BYTES, VERTICES_DATA_POS_OFFSET);
        GLES20.glEnableVertexAttribArray(getHandle("aTextureCoord"));
        GLES20.glVertexAttribPointer(getHandle("aTextureCoord"), VERTICES_DATA_UV_SIZE, GL_FLOAT, false, VERTICES_DATA_STRIDE_BYTES, VERTICES_DATA_UV_OFFSET);

        GLES20.glActiveTexture(GL_TEXTURE0);
        GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, texName);
        GLES20.glUniform1i(getHandle("sTexture"), 0);


        GLES20.glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

        GLES20.glDisableVertexAttribArray(getHandle("aPosition"));
        GLES20.glDisableVertexAttribArray(getHandle("aTextureCoord"));
        GLES20.glBindBuffer(GL_ARRAY_BUFFER, 0);
        GLES20.glBindTexture(GL_TEXTURE_2D, 0);

    }

    public int getRotate() {
        return rotate;
    }
}
